#include "tinyxmlmanager.h"

TinyXMLManager::TinyXMLManager()
{

}

TinyXMLManager::~TinyXMLManager()
{

}

bool TinyXMLManager::saveAttendeeToXML(const Attendee &attendee,
                                       const std::string &filePath)
{
    // 创建 XML 文档
    TiXmlDocument doc;
    // 添加 XML 声明
    TiXmlDeclaration* decl = new TiXmlDeclaration("1.0", "UTF-8", "");
    doc.LinkEndChild(decl);
    // 创建根元素
    TiXmlElement* root = new TiXmlElement("Attendee");


    doc.LinkEndChild(root);
    // 添加 name 元素
    TiXmlElement* nameElement = new TiXmlElement("Name");
    TiXmlText* nameText = new TiXmlText(attendee.name.c_str());
    nameElement->LinkEndChild(nameText);
    root->LinkEndChild(nameElement);
    // 添加 position 元素
    TiXmlElement* positionElement = new TiXmlElement("Position");
    TiXmlText* positionText = new TiXmlText(attendee.position.c_str());
    positionElement->LinkEndChild(positionText);
    root->LinkEndChild(positionElement);
    // 添加 age 元素
    TiXmlElement* ageElement = new TiXmlElement("Age");
    TiXmlText* ageText = new TiXmlText(std::to_string(attendee.age).c_str());
    ageElement->LinkEndChild(ageText);
    root->LinkEndChild(ageElement);
    // 添加 score 元素
    TiXmlElement* scoreElement = new TiXmlElement("Score");
    TiXmlText* scoreText = new TiXmlText(std::to_string(attendee.score).c_str());
    scoreElement->LinkEndChild(scoreText);
    root->LinkEndChild(scoreElement);
    // 添加 success 元素
    TiXmlElement* successElement = new TiXmlElement("Success");
    TiXmlText* successText = new TiXmlText(attendee.success ? "true" : "false");
    successElement->LinkEndChild(successText);
    root->LinkEndChild(successElement);
    // 保存 XML 文档到文件
    if (doc.SaveFile(filePath.c_str())) {
        return true;
    } else {
        std::cerr << "Failed to save XML file: " << filePath << std::endl;
        return false;
    }
}

bool TinyXMLManager::loadAttendeeFromXML(Attendee &attendee, const string &filePath)
{
    // 创建 XML 文档
    TiXmlDocument doc;
    // 加载 XML 文件
    if (!doc.LoadFile(filePath.c_str())) {
        std::cerr << "Failed to load XML file: " << filePath << std::endl;
        return false;
    }
    // 获取根元素
    TiXmlElement* root = doc.RootElement();
    if (!root) {
        std::cerr << "No root element found in XML file." << std::endl;
        return false;
    }
    // 解析 name 元素
    TiXmlElement* nameElement = root->FirstChildElement("Name");
    if (nameElement) {
        attendee.name = nameElement->GetText();
    }
    // 解析 position 元素
    TiXmlElement* positionElement = root->FirstChildElement("Position");
    if (positionElement) {
        attendee.position = positionElement->GetText();
    }
    // 解析 age 元素
    TiXmlElement* ageElement = root->FirstChildElement("Age");
    if (ageElement) {
        attendee.age = std::stoi(ageElement->GetText());
    }
    // 解析 score 元素
    TiXmlElement* scoreElement = root->FirstChildElement("Score");
    if (scoreElement) {
        attendee.score = std::stod(scoreElement->GetText());
    }
    // 解析 success 元素
    TiXmlElement* successElement = root->FirstChildElement("Success");
    if (successElement) {
        attendee.success = std::string(successElement->GetText()) == "true";
    }
    return true;
}

void TinyXMLManager::printAttendee(const Attendee &attendee)
{
    std::cout << "Name: " << attendee.name << std::endl;
    std::cout << "Position: " << attendee.position << std::endl;
    std::cout << "Age: " << attendee.age << std::endl;
    std::cout << "Score: " << attendee.score << std::endl;
    std::cout << "Success: " << (attendee.success ? "true" : "false") << std::endl;
}

bool TinyXMLManager::updateAttendeeInXML(const string &filePath, const string &fieldToUpdate, const string &newValue)
{
    // 加载 XML 文件
    TiXmlDocument doc;
    if (!doc.LoadFile(filePath.c_str())) {
        std::cerr << "Failed to load XML file: " << filePath << std::endl;
        return false;
    }
    // 获取根元素
    TiXmlElement* root = doc.RootElement();
    if (!root) {
        std::cerr << "No root element found in XML file." << std::endl;
        return false;
    }
    // 查找要更新的元素
    TiXmlElement* elementToUpdate = root->FirstChildElement(fieldToUpdate.c_str());
    if (elementToUpdate && elementToUpdate->GetText() != nullptr) {
        // 设置新值
        elementToUpdate->Clear(); // 清除旧的文本
        TiXmlText* newText = new TiXmlText(newValue.c_str());
        elementToUpdate->LinkEndChild(newText);
    } else {
        std::cerr << "Element " << fieldToUpdate << " not found in XML file." << std::endl;
        return false;
    }
    // 保存修改后的 XML 文件
    if (doc.SaveFile(filePath.c_str())) {
        return true;
    } else {
        std::cerr << "Failed to save XML file: " << filePath << std::endl;
        return false;
    }
}

TiXmlElement *TinyXMLManager::saveAttendeeToXMLElement(const Attendee &attendee)
{
    // 创建 Attendee 元素
    TiXmlElement* attendeeElement = new TiXmlElement("Attendee");
    // 添加 name 元素
    TiXmlElement* nameElement = new TiXmlElement("Name");
    TiXmlText* nameText = new TiXmlText(attendee.name.c_str());
    nameElement->LinkEndChild(nameText);
    attendeeElement->LinkEndChild(nameElement);
    // 添加 position 元素
    TiXmlElement* positionElement = new TiXmlElement("Position");
    TiXmlText* positionText = new TiXmlText(attendee.position.c_str());
    positionElement->LinkEndChild(positionText);
    attendeeElement->LinkEndChild(positionElement);
    // 添加 age 元素
    TiXmlElement* ageElement = new TiXmlElement("Age");
    TiXmlText* ageText = new TiXmlText(std::to_string(attendee.age).c_str());
    ageElement->LinkEndChild(ageText);
    attendeeElement->LinkEndChild(ageElement);
    // 添加 score 元素
    TiXmlElement* scoreElement = new TiXmlElement("Score");
    TiXmlText* scoreText = new TiXmlText(std::to_string(attendee.score).c_str());
    scoreElement->LinkEndChild(scoreText);
    attendeeElement->LinkEndChild(scoreElement);
    // 添加 success 元素
    TiXmlElement* successElement = new TiXmlElement("Success");
    TiXmlText* successText = new TiXmlText(attendee.success ? "true" : "false");
    successElement->LinkEndChild(successText);
    attendeeElement->LinkEndChild(successElement);
    // 返回构建好的 Attendee 元素
    return attendeeElement;
}

bool TinyXMLManager::saveXMLElementToXMLFile(TiXmlDocument &doc, const string &filePath)
{
    // 保存 XML 文档到文件
    if (doc.SaveFile(filePath.c_str())) {
        return true;
    } else {
        std::cerr << "Failed to save XML file: " << filePath << std::endl;
        return false;
    }
}

bool TinyXMLManager::saveXMLElementToXMLFile(const Attendee &attendee, const string &filePath)
{
    TinyXMLManager manager;
    // 创建 XML 文档
    TiXmlDocument doc;
    // 添加 XML 声明
    TiXmlDeclaration* decl = new TiXmlDeclaration("1.0", "UTF-8", "");
    doc.LinkEndChild(decl);

    TiXmlElement* attendeeElement1 = saveAttendeeToXMLElement(attendee);
    doc.LinkEndChild(attendeeElement1);

    // 保存文档到 XML 文件
    if (saveXMLElementToXMLFile(doc, filePath)) {
        std::cout << "XML file saved successfully." << std::endl;
        return true;
    }

    return false;

}



bool TinyXMLManager::saveMeetingToXML(const Meeting &meeting, const string &filePath)
{
    // 创建 XML 文档
    TiXmlDocument doc;
    // 添加 XML 声明
    TiXmlDeclaration* decl = new TiXmlDeclaration("1.0", "UTF-8", "");
    doc.LinkEndChild(decl);
    // 创建根元素 Meeting
    TiXmlElement* root = new TiXmlElement("Meeting");
    doc.LinkEndChild(root);
    // 添加 where 元素
    TiXmlElement* whereElement = new TiXmlElement("Where");
    TiXmlText* whereText = new TiXmlText(meeting.where.c_str());
    whereElement->LinkEndChild(whereText);
    root->LinkEndChild(whereElement);
    // 添加 time 元素
    TiXmlElement* timeElement = new TiXmlElement("Time");
    TiXmlText* timeText = new TiXmlText(std::to_string(meeting.time).c_str());
    timeElement->LinkEndChild(timeText);
    root->LinkEndChild(timeElement);
    // 添加 Attendees 元素
    TiXmlElement* attendeesElement = new TiXmlElement("Attendees");
    root->LinkEndChild(attendeesElement);
    // 遍历并添加每个参会者的信息
    for (const auto& attendee : meeting.attendees) {
        TiXmlElement* attendeeElement = new TiXmlElement("Attendee");

        // Name
        TiXmlElement* nameElement = new TiXmlElement("Name");
        TiXmlText* nameText = new TiXmlText(attendee.name.c_str());
        nameElement->LinkEndChild(nameText);
        attendeeElement->LinkEndChild(nameElement);

        // Position
        TiXmlElement* positionElement = new TiXmlElement("Position");
        TiXmlText* positionText = new TiXmlText(attendee.position.c_str());
        positionElement->LinkEndChild(positionText);
        attendeeElement->LinkEndChild(positionElement);

        // Age
        TiXmlElement* ageElement = new TiXmlElement("Age");
        TiXmlText* ageText = new TiXmlText(std::to_string(attendee.age).c_str());
        ageElement->LinkEndChild(ageText);  // 此处应添加文本
        attendeeElement->LinkEndChild(ageElement);

        // Score
        TiXmlElement* scoreElement = new TiXmlElement("Score");
        TiXmlText* scoreText = new TiXmlText(std::to_string(attendee.score).c_str());
        scoreElement->LinkEndChild(scoreText);  // 此处应添加文本
        attendeeElement->LinkEndChild(scoreElement);

        // Success
        TiXmlElement* successElement = new TiXmlElement("Success");
        TiXmlText* successText = new TiXmlText(attendee.success ? "true" : "false");
        successElement->LinkEndChild(successText);
        attendeeElement->LinkEndChild(successElement);

        // 将每个 attendeeElement 添加到 attendeesElement
        attendeesElement->LinkEndChild(attendeeElement);

    }
    // 保存 XML 文件
    if (doc.SaveFile(filePath.c_str())) {
        return true;
    } else {
        std::cerr << "Failed to save XML file: " << filePath << std::endl;
        return false;
    }
}

bool TinyXMLManager::loadMeetingFromXML(Meeting &meeting, const string &filePath)
{
    // 创建 XML 文档
    TiXmlDocument doc;
    // 加载 XML 文件
    if (!doc.LoadFile(filePath.c_str())) {
        std::cerr << "Failed to load XML file: " << filePath << std::endl;
        return false;
    }
    // 获取根元素
    TiXmlElement* root = doc.RootElement();
    if (!root) {
        std::cerr << "No root element found in XML file." << std::endl;
        return false;
    }
    // 解析 where 元素
    TiXmlElement* whereElement = root->FirstChildElement("Where");
    if (whereElement && whereElement->GetText() != nullptr) {
        meeting.where = whereElement->GetText();
    } else {
        meeting.where = ""; // 默认值
    }
    // 解析 time 元素
    TiXmlElement* timeElement = root->FirstChildElement("Time");
    if (timeElement && timeElement->GetText() != nullptr) {
        meeting.time = std::stoll(timeElement->GetText());
    } else {
        meeting.time = 0; // 默认值
    }
    // 解析 Attendees 元素
    TiXmlElement* attendeesElement = root->FirstChildElement("Attendees");
    if (attendeesElement) {
        TiXmlElement* attendeeElement = attendeesElement->FirstChildElement("Attendee");
        while (attendeeElement) {
            Attendee attendee;
            TiXmlElement* nameElement = attendeeElement->FirstChildElement("Name");
            if (nameElement && nameElement->GetText() != nullptr) {
                attendee.name = nameElement->GetText();
            } else {
                attendee.name = ""; // 默认值
            }
            TiXmlElement* positionElement = attendeeElement->FirstChildElement("Position");
            if (positionElement && positionElement->GetText() != nullptr) {
                attendee.position = positionElement->GetText();
            } else {
                attendee.position = ""; // 默认值
            }
            TiXmlElement* ageElement = attendeeElement->FirstChildElement("Age");
            if (ageElement && ageElement->GetText() != nullptr) {
                attendee.age = std::stoi(ageElement->GetText());
            } else {
                attendee.age = 0; // 默认值
            }
            TiXmlElement* scoreElement = attendeeElement->FirstChildElement("Score");
            if (scoreElement && scoreElement->GetText() != nullptr) {
                attendee.score = std::stod(scoreElement->GetText());
            } else {
                attendee.score = 0.0; // 默认值
            }
            TiXmlElement* successElement = attendeeElement->FirstChildElement("Success");
            if (successElement && successElement->GetText() != nullptr) {
                attendee.success = std::string(successElement->GetText()) == "true";
            } else {
                attendee.success = false; // 默认值
            }
            meeting.attendees.push_back(attendee);
            attendeeElement = attendeeElement->NextSiblingElement("Attendee");
        }
    }
    return true;
}

void TinyXMLManager::printMeeting(const Meeting &meeting)
{
    std::cout << "Meeting Location: " << meeting.where << std::endl;
    std::cout << "Meeting Time: " << meeting.time << std::endl;
    std::cout << "Attendees: " << std::endl;
    for (const auto& attendee : meeting.attendees) {
        std::cout << "  Name: " << attendee.name << std::endl;
        std::cout << "  Position: " << attendee.position << std::endl;
        std::cout << "  Age: " << attendee.age << std::endl;
        std::cout << "  Score: " << attendee.score << std::endl;
        std::cout << "  Success: " << (attendee.success ? "true" : "false") << std::endl;
        std::cout << std::endl;
    }

}

string TinyXMLManager::getToString(int value)
{
    std::ostringstream oss;
    oss << value;
    return oss.str();
}

string TinyXMLManager::getToString(short value)
{
    std::ostringstream oss;
    oss << value;
    return oss.str();
}

string TinyXMLManager::getToString(long value)
{
    std::ostringstream oss;
    oss << value;
    return oss.str();
}

string TinyXMLManager::getToString(long long value)
{
    std::ostringstream oss;
    oss << value;
    return oss.str();
}

string TinyXMLManager::getToString(float value)
{
    std::ostringstream oss;
    oss << value;
    return oss.str();
}

string TinyXMLManager::getToString(double value)
{
    std::ostringstream oss;
    oss << value;
    return oss.str();
}

string TinyXMLManager::getToString(bool value)
{
    std::ostringstream oss;
    oss << std::boolalpha << value;
    return oss.str();
}

string TinyXMLManager::getToString(char value)
{
    std::ostringstream oss;
    oss << value;
    return oss.str();
}

string TinyXMLManager::getToString(unsigned char value)
{
    std::ostringstream oss;
    oss << value;  // Output the character directly
    return oss.str();
}

string TinyXMLManager::getToString(unsigned short value)
{
    std::ostringstream oss;
    oss << value;
    return oss.str();
}

string TinyXMLManager::getToString(unsigned int value)
{
    std::ostringstream oss;
    oss << value;
    return oss.str();
}

string TinyXMLManager::getToString(unsigned long value)
{
    std::ostringstream oss;
    oss << value;
    return oss.str();
}

string TinyXMLManager::getToString(unsigned long long value)
{
    std::ostringstream oss;
    oss << value;
    return oss.str();
}


string TinyXMLManager::getToString(signed char value)
{
    std::ostringstream oss;
    oss << /*static_cast<int>*/(value);  // Convert to int to avoid character output
    return oss.str();
}

string TinyXMLManager::getToString(const char *value)
{
    return string(value);
}

string TinyXMLManager::getToString(const unsigned char *value, size_t length)
{
    return string(reinterpret_cast<const char*>(value), length);
}

unsigned char TinyXMLManager::getUnsigneCharFromString(string value)
{
    unsigned short temp = std::stoul(value);
    if (temp > 255) {
        throw std::out_of_range("Value out of range for unsigned char");
    }
    return static_cast<unsigned char>(temp);
}

unsigned short TinyXMLManager::getUnsigneShortFromString(string value)
{
return std::stoul(value);
}

unsigned int TinyXMLManager::getUnsigneIntFromString(string value)
{
return std::stoul(value);
}

int TinyXMLManager::getIntFromString(string value)
{
 return std::stoi(value);
}

short TinyXMLManager::getShorttFromString(string value)
{
    int temp = std::stoi(value);
    if (temp < SHRT_MIN || temp > SHRT_MAX) {
        throw std::out_of_range("Value out of range for short");
    }
    return static_cast<short>(temp);
}

float TinyXMLManager::getFloatFromString(string value)
{
  return std::stof(value);
}

double TinyXMLManager::getDoubleFromString(string value)
{
 return std::stod(value);
}

bool TinyXMLManager::getBoolFromString(string value)
{
    std::istringstream ss(value);
    bool b;
    ss >> std::boolalpha >> b;
    return b;
}


